<?php

namespace pmvc\ioc\xml;

use pmvc\cache\Cache;

use pmvc\ioc\PropertyDescriptor;
use pmvc\ioc\ObjectDescriptor;
use pmvc\ioc\annotation\FileAutowireCandidateProvider;

use pmvc\util\FileUtil;
use pmvc\util\XMLUtil;

use DOMElement;
use Exception;

/**
 * An extension for wiring objects using their autowire
 * annotations.
 *
 */
class AutowireExtension
	implements Extension {

	/**
	 * {@inheritDoc}
	 */
	public function process(DOMElement $element, ParseContext $pc) {

		// get attributes
		$id 		= XMLUtil::getAttributeValue($element, "id");
		$file		= XMLUtil::getAttributeValue($element, "file");
		$cacheIdRef	= XMLUtil::getAttributeValue($element, "cacheIdRef");
		$useCache	= XMLUtil::getAttributeValue($element, "useCache", "true");
		$ttl		= XMLUtil::getAttributeValue($element, "ttl", Cache::ONE_HOUR);
		
		// makes ure we have an id
		if (!isset($id)) {
			$id = uniqid('', TRUE) . '#AutowireDescriptorRegistrar';
		}
		
		// create descriptor for provider
		$providerId = $id."::FileAutowireCandidateProvider";
		$providerDesc = new ObjectDescriptor(
			$providerId, 'pmvc\ioc\annotation\FileAutowireCandidateProvider', $providerId);
		$providerDesc->properties []= new PropertyDescriptor("fileName", $file, PropertyDescriptor::TYPE_STRING);
		$providerDesc->properties []= new PropertyDescriptor("relativeFileName", $pc->getXmlFile(), PropertyDescriptor::TYPE_STRING);
		$providerDesc->properties []= new PropertyDescriptor("useCache", $useCache, PropertyDescriptor::TYPE_BOOLEAN);
		$providerDesc->properties []= new PropertyDescriptor("ttl", $ttl, PropertyDescriptor::TYPE_INTEGER);
		if (isset($cacheIdRef)) {
			$providerDesc->properties []= new PropertyDescriptor("cache", $cacheIdRef, PropertyDescriptor::TYPE_REF);
		}
		
		// create descritor
		$descriptor = new ObjectDescriptor(
				$id, 'pmvc\ioc\annotation\AutowireDescriptorRegistrar', $id);
		$descriptor->properties []= new PropertyDescriptor("provider", $providerId, PropertyDescriptor::TYPE_REF);
		
		// add it
		$objectFactory = $pc->getObjectFactory();
		$objectFactory->addObjectDescriptor($providerDesc);
		$objectFactory->addObjectDescriptor($descriptor);
	}
}